<template>
  <div>
     <!--  this.$emit('changeCategory',{categoryId:category3Id,level:3}) -->
    <el-card>
          <CategorySelector  @changeCategory="changeCategory" :isShowList="isShowList"></CategorySelector>
    </el-card>

    <el-card style="margin-top: 20px">
        <!-- 这是列表页面 -->
        <div  v-show="isShowList">
              <el-button type="primary"  icon="el-icon-plus"   :disabled="!category3Id" @click="showAddDiv">添加属性</el-button>
            <el-table   :data="attrList"
                border
                style="width: 100%">
                <el-table-column
                    type="index"
                    align="center"
                    label="序号"
                    width="80">
                </el-table-column>
                <el-table-column
                    prop="attrName"
                    label="属性名称"
                    width="150">
                </el-table-column>
                <el-table-column
                    label="属性值列表"
                    width="width">
                    <template slot-scope="{row}">
                          <el-tag type="primary"  v-for="attrValue in row.attrValueList" :key="attrValue.id">
                              {{attrValue.valueName}}</el-tag>  
                    </template>
                </el-table-column>
                <el-table-column
                    prop="prop"
                    label="操作"
                    width="150">
                    <template slot-scope="{row}">
                        <HintButton type="warning"  icon="el-icon-edit"  size="mini" title="修改"  @click="showUpdateDiv(row)"></HintButton>
                        <el-popconfirm
                            :title="`你确定要删除${row.attrName}吗？`"  @onConfirm="deleteAttr(row)">
                        <HintButton   slot="reference"  type="danger" 
                                 icon="el-icon-delete"  size="mini" title="删除" ></HintButton>
                            </el-popconfirm>

                    </template>
                </el-table-column>
            </el-table>
        </div>
            
            <!-- 这是一个添加或者修改页面 -->
            <div v-show="!isShowList">
                <el-form :inline="true" :model="attrForm">
                        <el-form-item label="属性名">
                            <el-input   placeholder="请输入属性名"  v-model="attrForm.attrName"></el-input>
                        </el-form-item>
                </el-form>
                <el-button  :disabled="!attrForm.attrName" type="primary" icon="el-icon-plus"  @click="addAttrValue">添加属性值</el-button>
                <el-button  @click="isShowList = true">取消</el-button>

                <el-table   :data="attrForm.attrValueList"
                    border
                    style="width: 100%;margin:20px 0" >
                    <el-table-column
                        type="index" 
                        align="center"
                        label="序号"
                        width="80">
                    </el-table-column>
                    <el-table-column
                        prop="prop"
                        label="属性值名称"
                        width="width">
                             <template  slot-scope="{row,$index}">
                                    <el-input  @blur="toLook(row)"  @keyup.enter.native="toLook(row)"  v-if="row.isEdit" v-model="row.valueName"    
                                        size="mini" :ref="$index"   placeholder="请输入属性值名称"   ></el-input>
                                    <span  @click="toEdit(row,$index)"  v-else    style="display:block;width:100%">{{row.valueName}}</span>
                             </template>
 
                    </el-table-column>
                    <el-table-column
                        prop="prop"
                        label="操作"
                        width="width">
                       <template slot-scope="{row,$index}">
                           <el-popconfirm
                                :title="`你确定要删除${row.valueName}吗？`"   @onConfirm="attrForm.attrValueList.splice($index,1)">
                            <HintButton  slot="reference" type="danger"  icon="el-icon-delete" size="mini" title="删除"></HintButton>
                                </el-popconfirm>  
                       </template>
                    </el-table-column>
                </el-table>

                 <el-button type="primary"  @click="save" :disabled="!attrForm.attrValueList.length">保存</el-button>
                 <el-button @click="isShowList = true">取消</el-button>
            </div>
    </el-card>
  </div>
</template>

<script>
import  cloneDeep from 'lodash/cloneDeep'
export default {
  name: "Attr",
  data() {
    return {
        category1Id:'', //一级分类id
        category2Id:'', //二级分类id
        category3Id:'', //三级分类id
        attrList:[],  //属性数据列表

        isShowList:true,

        //根据接口文档用来收集数据的
        attrForm:{
             //第一步：先让table去展示这个属性值数组
             //第二步：点击添加属性值按钮，往属性值数组当中添加一个数据
             //这个数据的格式是一个对象，对象里面的属性包含attrId还有valueName
             //添加这个对象的时候，valueName是空的，留着后期让用户输入的
             //第三步：数据添加会造成table表格会展示一行，我们可以在这行当中显示一个input框
             //让用户去输入想要的属性值名称
            attrName: "",
            attrValueList: [//这个数组是用来收集用户输入的value的
                // {
                    // attrId: 0,   //attrId的值，是当前这个属性值所属属性值的id（attrId是当前属性的id，也就是attrForm的id）
                    // valueName: ''
                // }
            ],
            categoryId: 0,
            categoryLevel: 3, //添加或者新增页展示的是3级里面的数据
        }
    };
  },
  methods:{
      //判断是几级分类，三级分类需要展示到下部页面
    changeCategory({categoryId,level}){
        if(level === 1){
            //清空父组件的23级id及属性列表数据
            this.category2Id=''
            this.category3Id=''
            this.attrList =[]


           this.category1Id = categoryId
        }else if(level === 2){
            //清空父组件的3级id及属性列表数据
            this.category3Id=''
            this.attrList =[]

            this.category2Id = categoryId
        }else{
            this.category3Id = categoryId

            //发请求获取属性列表
            this.getAttrList()
        }
    },

    //请求获取属性列表
     async getAttrList(){
         let {category1Id,category2Id,category3Id} = this
         try {
            const result =  await  this.$API.attr.getList(category1Id,category2Id,category3Id)
            if(result.code === 200 || result.code === 20000){
                 this.attrList = result.data
            }else {
                 this.$message.error('获取属性列表失败')
            }
         } catch (error) {
                 this.$message.error('请求获取属性列表失败')
         }
         
        },

        //点击添加‘添加属性按钮’切换到‘添加修改页面’
        showAddDiv(){
            this.isShowList = false


            //每次点击添加属性值按钮时，清空上一次的数据,就是把attrForm清空
            this.attrForm = {
            attrName: "",
            attrValueList: [],
            categoryId: this.category3Id,//这里可以写3级分类的id因为这里不是初始化，已经是后期，data已经初始化完了
            categoryLevel: 3, 
        }
        },

        //点击新添加属性值按钮，往中间列表中新增属性值，因为没有数据来源，所以里面写空的占位，让用户输入
        addAttrValue(){
              this.attrForm.attrValueList.push({
                  //添加属性是可以添加属性值的，此时这个id是undefined，因为添加属性的时候属性是没有id的
                  //修改属性也是可以添加属性值的，修改属性，属性当中是有id的
                    attrId : this.attrForm.id, 
                    valueName:'',
                    isEdit:true,
              })

              //自动获取焦点
                   this.$nextTick(() => { //nextTick当数据更新了，页面还没来得及渲染，就立即执行里面的回调函数
        				this.$refs[this.attrForm.attrValueList.length - 1].focus()
      				})
              
              
        },

        //点击修改属性按钮，切换到修改页
        showUpdateDiv(row){
             this.isShowList = false 
             //这个要用深拷贝，原因：列表页点击修改的时候会把这个里面的三级分类信息转入到修改页，
             //如果不用深拷贝，当在修改页，点修改，修改信息后再取消，会导致修改的信息转入到列表页展示
            //  this.attrForm = {...row}  //这是浅拷贝，这里不能用
                this.attrForm = cloneDeep(row)

                // this.attrForm.attrValueList.forEach(item=>item.isEdit = false) //新添加的isEdit属性不是响应式，所以不能用
                this.attrForm.attrValueList.forEach(item=>this.$set(item,'isEdit',false))
        },

        //添加模式标识数据
        //每个属性值无论新添加的还是老的都有自己的添加模式（input）和查看模式（span）
        //对于新添加的属性值，一上来显示就是input（编辑模式）老的属性值一上来就是span（查看模式）
        //说白了就是给每个属性值添加标识数据
        

        //点击span切换为input，从查看模式变为编辑模式
        toEdit(row,index){
           row.isEdit = true

           //自动获取焦点
          this.$nextTick(()=>{
              this.$refs[index].focus()
          })
        },

        //input失去焦点或者回车，变成span，从编辑模式变成查看模式
        toLook(row){
            let valueName = row.valueName
            // input在切换为span之前要判断数据合法性,用户输入值不能为空，不能有重复的
			// 	1、数据是不是空的
            if(row.valueName.trim() === ''){
                //  this.$message.error('输入的属性值名称不能为空')
                 row.valueName = ''
            }
            // 	2、除了自己以外，输入的数据是不是和其它的属性值名称重复
            let isRepeat =  this.attrForm.attrValueList.some(item => {
                if(item !== row)//除了自己以外
                 return item.valueName === valueName
            })
            if(isRepeat){
                   this.$message.error('输入的属性值名称不能为空')
                    row.valueName = ''
                    return
            }
           

             row.isEdit = false
        },

        //点击修改页的"保存按钮"，保存操作，需要发请求
        async  save(){
               //1.获取参数
                 let attr = this.attrForm
               //2.整理参数
                    // 1、属性值名称如果为空串，从属性值列表当中去除
				    // 2、属性值当中去除isEdit属性
				    // 3、属性值列表如果没有属性值，不发请求
                // attr.attrValueList = attr.attrValueList.filter(item=> item.valueName.trim() !== '')
                //  attr.attrValueList.forEach(item=>delete item.isEdit)
                    attr.attrValueList = attr.attrValueList.filter(item=>{
                        if(item.valueName.trim() !== ''){
                            delete item.isEdit
                            return true
                        }
                    })


                 if(!attr.attrValueList.length){
                     return
                 }
               //3.发请求
               try {
                const result = await  this.$API.attr.addOrUpdate(attr)
                if(result.code === 200 || result.code === 20000){
                        //提示保存属性成功
                        this.$message.success('保存属性成功')
                        //返回到属性列表页
                     this.isShowList = true
                     //重新获取列表页数据
                     this.getAttrList()

                }else{
                    this.$message.error('保存属性失败')
                }
               } catch (error) {
                   this.$message.error('请求保存属性失败')
               }
               
               //4.成功干啥
               //5.失败干啥

        },

        //点击列表页"删除按钮"删除属性
        async deleteAttr(row){
            try {
              const result = await  this.$API.attr.remove(row.id)
              if(result.code === 200 || result.code === 20000){
                    //提示 
                    this.$message.success('删除属性成功')
                    //重新获取数据
                    this.getAttrList()
              }else {
                    //提示
                    this.$message.error('删除属性失败')
              }
            } catch (error) {
                this.$message.error('请求删除属性失败')
            }
        }
  }
};
</script>

<style>
</style>